/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.primecodegen.core;

import com.primecodegen.common.DataModelAttributes.DataModelAttributesDAO;
import com.primecodegen.common.DataModelAttributes.DataModelAttributesTable;
import com.primecodegen.common.DataModelObject.DataModelObjectTable;
import com.primecodegen.common.DataModelProject.DataModelProjectTable;
import com.primecodegen.common.DmAttrProp.DmAttrPropDAO;
import com.primecodegen.common.DmAttrProp.DmAttrPropTable;
import com.primecodegen.common.DmObjProp.DmObjPropDAO;
import com.primecodegen.common.DmObjProp.DmObjPropTable;
import com.primecodegen.common.DmPrjProp.DmPrjPropDAO;
import com.primecodegen.common.DmPrjProp.DmPrjPropTable;
import com.primecodegen.common.GeneratedTargets.GeneratedTargetsDAO;
import com.primecodegen.common.GeneratedTargets.GeneratedTargetsTable;
import com.primecodegen.util.util;
import freemarker.template.TemplateException;
import java.io.Writer;
import java.util.*;

import freemarker.template.Configuration;

import freemarker.template.Template;
import java.io.File;
import java.io.PrintWriter;

/**
 *
 * @author Mohammad
 * GenerateToPath should be like "com\\ats\\me" means it must starts and ends without 
 */
public class processTemplate_1 {

    Map<String, Object> prjMap = new HashMap<String, Object>();
    Map<String, Object> objMap = new HashMap<String, Object>();
    Map<String, Object> attrMap = new HashMap<String, Object>();
    //
    DmPrjPropDAO dmPrjPropDAO = new DmPrjPropDAO();
    DmObjPropDAO dmObjPropDAO = new DmObjPropDAO();
    DmAttrPropDAO dmAttrPropDAO = new DmAttrPropDAO();
    //
    DataModelAttributesDAO dataModelAttributesDAO = new DataModelAttributesDAO();
    //
    DmPrjPropTable prjPropTable = new DmPrjPropTable();
    DmObjPropTable dmObjPropTable = new DmObjPropTable();
    DmAttrPropTable attrPropTable = new DmAttrPropTable();
    //
    List<Object> attributesList = new ArrayList<Object>();
    //
    DataModelProjectTable prjTable = new DataModelProjectTable();
    DataModelObjectTable objTable = new DataModelObjectTable();
    DataModelAttributesTable attrTable = new DataModelAttributesTable();

    public void doProcessing(DataModelProjectTable dataModelProjectTables,
            DataModelObjectTable[] selectedObjectTables,
            GeneratedTargetsTable[] targetsTables, String generateToRoot) throws TemplateException {

        DataModelObjectTable criteriaObjTable = new DataModelObjectTable();
        DataModelAttributesTable criteriaAttrTable = new DataModelAttributesTable();
        //
        String createToPath = "";
        String writeToFile = "";
        GeneratedTargetsDAO targetsDAO = new GeneratedTargetsDAO();
        GeneratedTargetsTable generatedTargetsTable = new GeneratedTargetsTable();
        try {
            File f = new File(util.getBundleValue("ABSOLUTE_TEMPLATE_DIRECTORY"));
            boolean exists = f.exists();
            System.out.print(exists);
            Configuration cfg = new Configuration();
            cfg.setDirectoryForTemplateLoading(f);

            Template temp;


            for (int i = 0; i < targetsTables.length; i++) {

                generatedTargetsTable = (GeneratedTargetsTable) targetsTables[i];
//                generatedTargetsTable = (GeneratedTargetsTable) targetsDAO.getByID(generatedTargetsTable.getID());

                temp = cfg.getTemplate(generatedTargetsTable.getTemplate());

                prjPropTable.setDataModelProject_ID(dataModelProjectTables.getID());
                prjPropTable.setFilter(true);
                processProjectRules(dmPrjPropDAO.getByCriterionOrderedBy(prjPropTable, null));

                for (int j = 0; j < selectedObjectTables.length; j++) {

                    objTable = (DataModelObjectTable) selectedObjectTables[j];

                    dmObjPropTable.setDataModelObject_ID(objTable.getID());
                    dmObjPropTable.setFilter(true);
                    processObjectsRules(dmObjPropDAO.getByCriterionOrderedBy(dmObjPropTable, null));

                    criteriaAttrTable.setDataModelObject_ID(objTable.getID());
                    criteriaAttrTable.setFilter(true);
                    Iterator itAttr = dataModelAttributesDAO.getByCriterionOrderedBy(criteriaAttrTable, null).iterator();
                    while (itAttr.hasNext()) {//Iterate through array of Attributes to be processed

                        attrMap = new HashMap();
                        attrTable = (DataModelAttributesTable) itAttr.next();
                        attrPropTable.setDataModelAttributes_ID(attrTable.getID());
                        attrPropTable.setFilter(true);
                        processAttributesRules(dmAttrPropDAO.getByCriterionOrderedBy(attrPropTable, null), attrTable);

                    }
                    objMap.put("attributesList", attributesList);
                    
//                    createToPath = processFilePath(util.getBundleValue("JAVA_SRC_PATH_ABSOLUTE") + generatedTargetsTable.getGenerateTo());
                    createToPath = processFilePath(generateToRoot + generatedTargetsTable.getGenerateTo());
                    writeToFile =processFilePath( createToPath + "\\" + generatedTargetsTable.getFilePreName());
                    
                    util.createDirectories(createToPath);
                    util.createFile(writeToFile);
                    Writer out = new PrintWriter(new File(writeToFile));
                    temp.process(prjMap, out);

                    criteriaAttrTable = new DataModelAttributesTable();
                    attributesList=new ArrayList<Object>();
                    objMap=new HashMap<String, Object>();
                    out.flush();
                    out.close();
                }


            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public String processFilePath(String path){
        String replace = path
                                 .replace("#{objName}", objTable.getCode())
                                 .replace("#{objNameBeanPattern}",util.toCamelCaseFirstLower( objTable.getCode()))
                                 .replace("#{objNameCamelCase}",util.toCamelCase(objTable.getCode()));
        System.out.println(replace);
        return replace;

    }

    private void processProjectRules(ArrayList<DmPrjPropTable> dmPrjPrps) {
        prjMap = new HashMap<String, Object>();
        DmPrjPropTable dmPrjPropTable;

        Iterator it = dmPrjPrps.iterator();
        while (it.hasNext()) {
            dmPrjPropTable = new DmPrjPropTable();
            dmPrjPropTable = (DmPrjPropTable) it.next();
            prjMap.put(dmPrjPropTable.getPrjPropCode(), dmPrjPropTable.getValue());
        }


    }

    private void processObjectsRules(ArrayList<DmObjPropTable> dmObjPrps) {
        objMap = new HashMap<String, Object>();
        objMap.put(TemplateConstants.OBJECT_CODE,objTable.getCode());
        objMap.put(TemplateConstants.OBJECT_CODE_UPPERCASE,objTable.getCode().toUpperCase());
        objMap.put(TemplateConstants.OBJECT_CODE_LOWERCASE,objTable.getCode().toLowerCase());
        objMap.put(TemplateConstants.OBJECT_CODE_CAMLE_CASE, util.toCamelCase(objTable.getCode()));
        objMap.put(TemplateConstants.OBJECT_CODE_BEAN_PATTERN, util.toCamelCaseFirstLower(objTable.getCode()));
        
        DmObjPropTable dmObjPropTable;
        Iterator it = dmObjPrps.iterator();
        while (it.hasNext()) {
            dmObjPropTable = new DmObjPropTable();
            dmObjPropTable = (DmObjPropTable) it.next();
            objMap.put(dmObjPropTable.getObjPropCode(), dmObjPropTable.getValue());
        }
        prjMap.put("ObjectMap", objMap);

    }

    private void processAttributesRules(ArrayList<DmAttrPropTable> dmAttrPrps, DataModelAttributesTable attributesTable) {
        attrMap = new HashMap<String, Object>();

        attrMap.put(TemplateConstants.ATTRIBUTE_CODE, attributesTable.getCode());
        attrMap.put(TemplateConstants.ATTRIBUTE_CODE_UPPERCASE, attributesTable.getCode().toUpperCase());
        attrMap.put(TemplateConstants.ATTRIBUTE_CODE_LOWERCASE, attributesTable.getCode().toLowerCase());
        attrMap.put(TemplateConstants.ATTRIBUTE_CODE_CAMEL_CASE, util.toCamelCase(attributesTable.getCode()));
        attrMap.put(TemplateConstants.ATTRIBUTE_CODE_BEAN_PATTERN, util.toCamelCaseFirstLower(attributesTable.getCode()));
        attrMap.put(TemplateConstants.ATTRIBUTE_CODE_DATATYPE, attributesTable.getDataType());
        attrMap.put(TemplateConstants.ATTRIBUTE_IS_FOREIGN_KEY, attributesTable.getForeignKey());
        attrMap.put(TemplateConstants.ATTRIBUTE_IS_PRIMARY_KEY, attributesTable.getPrimaryKey());

        DmAttrPropTable dmAttrPropTable;
        Iterator it = dmAttrPrps.iterator();
        while (it.hasNext()) {
            dmAttrPropTable = new DmAttrPropTable();
            dmAttrPropTable = (DmAttrPropTable) it.next();
            attrMap.put(dmAttrPropTable.getAttrPropCode(), dmAttrPropTable.getValue());
        }
        attributesList.add(attrMap);


    }
}
